﻿using FaissOperation.FaissIndexFlat;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace FaissOperation.FaissIndex.Native
{
    internal static class FaissNative
    {
#if LINUX
// 优先使用 AVX2 优化库
private const string DllName = "libfaiss_avx2.so"; 
#endif

#if WINDOWS
        // x64/x86 使用 faiss.dll
        private const string DllName = "faiss_c.dll";
#endif

        [DllImport(DllName, EntryPoint = "faiss_IndexFlat_new", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_IndexFlat_new(out IntPtr index, int d, FaissMetricType metric);

        [DllImport(DllName, EntryPoint = "faiss_IndexIVFFlat_new", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_IndexIVFFlat_new(out IntPtr index, IntPtr quantizer, int d, int nlist, FaissMetricType metric);

        [DllImport(DllName, EntryPoint = "faiss_Index_free", CallingConvention = CallingConvention.Cdecl)]
        public static extern void faiss_Index_free(IntPtr index);

        [DllImport(DllName, EntryPoint = "faiss_Index_add", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_Index_add(IntPtr index, long n, float[] x);

        [DllImport(DllName, EntryPoint = "faiss_Index_search", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_Index_search(IntPtr index, long n, float[] x, long k, float[] distances, long[] labels);

        [DllImport(DllName, EntryPoint = "faiss_Index_reset", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_Index_reset(IntPtr index);

        // 重要：训练函数也需要返回错误码并固定内存
        [DllImport(DllName, EntryPoint = "faiss_Index_train", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_Index_train(IntPtr index, long n, float[] x);

        [DllImport(DllName, EntryPoint = "faiss_Index_is_trained", CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.I1)]
        public static extern bool faiss_Index_is_trained(IntPtr index);

        // 添加一些有用的调试函数
        [DllImport(DllName, EntryPoint = "faiss_Index_ntotal", CallingConvention = CallingConvention.Cdecl)]
        public static extern long faiss_Index_ntotal(IntPtr index);

        [DllImport(DllName, EntryPoint = "faiss_Index_d", CallingConvention = CallingConvention.Cdecl)]
        public static extern int faiss_Index_d(IntPtr index);

    }

}
